//
//  WJPDFBoxProvider.swift
//  PDFSign
//
//  Created by 李永彬 on 2025/9/25.
//

import Foundation
import PDFKit

class WJPDFBoxProvider: NSObject, PDFPageOverlayViewProvider {
    weak var pdfView: PDFView?
    private var pageToCanvasViewMapping = [PDFPage: WJOverlayView]()
    
    weak var referencePDFDocument: PDFDocument?
    
    // 改为管理多个 box 的模板（用于新创建的 box）
    private var boxViewTemplates: [WJPDFSignatureBoxView] = [] {
        didSet {
            updateAllOverlayViews()
        }
    }
    
    // 添加新的 box 模板
    func addBoxView(_ boxView: WJPDFSignatureBoxView) {
        // 创建新的实例，避免引用同一个对象
        let newBoxView = WJPDFSignatureBoxView()
        newBoxView.signatureImage = boxView.signatureImage
        newBoxView.frame = boxView.frame
        
        boxViewTemplates.append(newBoxView)
    }
    
    // 移除所有 box 模板
    func clearAllBoxViews() {
        boxViewTemplates.removeAll()
    }
    
    // 为特定页面添加 box
    func addBoxViewToPage(_ page: PDFPage, boxView: WJPDFSignatureBoxView? = nil) {
        guard let overlayView = pageToCanvasViewMapping[page] else { return }
        unSelectedAllBoxViewFromPage(page)
        let boxToAdd: WJPDFSignatureBoxView
        if let providedBoxView = boxView {
            boxToAdd = providedBoxView
        } else if let template = boxViewTemplates.last {
            // 使用最后一个模板创建新实例
            boxToAdd = WJPDFSignatureBoxView()
            boxToAdd.signatureImage = template.signatureImage
            boxToAdd.frame = template.frame
        } else {
            // 创建默认的 box
            boxToAdd = WJPDFSignatureBoxView()
            boxToAdd.frame = CGRect(x: 50, y: 50, width: 200, height: 100)
        }
        
        overlayView.addBoxView(boxToAdd)
        refreshPDFOverlayViews()
    }
    
    // 从特定页面移除所有 box
    func removeAllBoxViewsFromPage(_ page: PDFPage) {
        guard let overlayView = pageToCanvasViewMapping[page] else { return }
        overlayView.removeAllBoxViews()
        refreshPDFOverlayViews()
    }
    
    // 从特定页面移除指定的 box
    func removeBoxViewFromPage(_ page: PDFPage, boxView: WJPDFSignatureBoxView) {
        guard let overlayView = pageToCanvasViewMapping[page] else { return }
        overlayView.removeBoxView(boxView)
        refreshPDFOverlayViews()
    }
    
    func unSelectedAllBoxViewFromPage(_ page: PDFPage) {
        guard let overlayView = pageToCanvasViewMapping[page] else { return }
        overlayView.unSelectedAllBoxView()
    }
    
    // 获取特定页面的所有 box
    func getBoxViewsForPage(_ page: PDFPage) -> [WJPDFSignatureBoxView] {
        return pageToCanvasViewMapping[page]?.boxViews ?? []
    }

    // PDFPageOverlayViewProvider 方法
    func pdfView(_ view: PDFView, overlayViewFor page: PDFPage) -> UIView? {
        let overlayView: WJOverlayView
        
        if let existingView = pageToCanvasViewMapping[page] {
            overlayView = existingView
        } else {
            overlayView = WJOverlayView()
            pageToCanvasViewMapping[page] = overlayView
            
            // 为新页面添加现有的模板 box
            for template in boxViewTemplates {
                let newBoxView = WJPDFSignatureBoxView()
                newBoxView.signatureImage = template.signatureImage
                newBoxView.frame = template.frame
                overlayView.addBoxView(newBoxView)
            }
        }
        
        overlayView.isUserInteractionEnabled = true
        (page as? WJPDFPage)?.overlayView = overlayView
        return overlayView
    }
    
    func pdfView(_ pdfView: PDFView, willDisplayOverlayView overlayView: UIView, for page: PDFPage) {
        // 可以在这里进行额外的配置
    }
    
    func pdfView(_ pdfView: PDFView, willEndDisplayingOverlayView overlayView: UIView, for page: PDFPage) {
        // 可以在这里保存状态
    }
    
    // 更新所有 overlay 视图
    private func updateAllOverlayViews() {
        for (_, overlayView) in pageToCanvasViewMapping {
            overlayView.removeAllBoxViews()
            
            // 重新添加所有模板 box
            for template in boxViewTemplates {
                let newBoxView = WJPDFSignatureBoxView()
                newBoxView.signatureImage = template.signatureImage
                newBoxView.frame = template.frame
                overlayView.addBoxView(newBoxView)
            }
        }
        
        refreshPDFOverlayViews()
    }
    
    // 刷新 PDF 覆盖视图
    private func refreshPDFOverlayViews() {
        pdfView?.layoutDocumentView()
        pdfView?.setNeedsDisplay()
    }
    
    // 启用/禁用编辑
    func setEditingEnabled(_ enabled: Bool) {
        pageToCanvasViewMapping.values.forEach { $0.isEditingEnabled = enabled }
    }
    
    private func saveSignaturesToNewPDF() -> PDFDocument? {
        guard let originalDocument = referencePDFDocument else {
            print("错误：referencePDFDocument 未设置")
            return nil
        }
        
        // 关键：直接复制整个文档数据，保留所有结构
        guard let documentData = originalDocument.dataRepresentation(),
              let newDocument = PDFDocument(data: documentData) else {
            return nil
        }
        
        let pageCount = newDocument.pageCount
        
        for pageIndex in 0..<pageCount {
            guard let currentPage = newDocument.page(at: pageIndex),
                  let originalPage = originalDocument.page(at: pageIndex) else {
                continue
            }
            
            // 将签名绘制为新的注解添加到现有页面（保留原始注解）
            addSignaturesAsAnnotations(to: currentPage, from: originalPage)
        }
        
        return newDocument
    }

    /// 将签名添加为新的PDF注解（不破坏现有注解）
    private func addSignaturesAsAnnotations(to page: PDFPage, from originalPage: PDFPage) {
        let signaturesForPage = getBoxViewsForPage(originalPage)
        let mediaBox = page.bounds(for: .mediaBox)
        
        for signatureBox in signaturesForPage {
            guard let signatureImage = signatureBox.getSignatureImage() else { continue }
            
            let boxFrame = signatureBox.frame
            let pdfY = mediaBox.height - boxFrame.origin.y - boxFrame.height
            let annotationBounds = CGRect(
                x: boxFrame.origin.x,
                y: pdfY,
                width: boxFrame.width,
                height: boxFrame.height
            )
            
            // 只提取旋转角度应用到图像
            let angle = atan2(signatureBox.transform.b, signatureBox.transform.a)
            let rotatedImage = signatureImage.rotated(by: angle) ?? signatureImage
            
            let imageAnnotation = WJPDFImageAnnotation(image: rotatedImage, bounds: annotationBounds)
            page.addAnnotation(imageAnnotation)
        }
    }

    /// 将签名后的PDF保存到本地文件
    /// - Parameter url: 要保存到的文件URL
    /// - Returns: 是否成功
    @discardableResult
    func saveNewPDFToFile(at url: URL) -> Bool {
        guard let newPDFDocument = saveSignaturesToNewPDF() else {
            return false
        }
//        return newPDFDocument.write(to: url)
        return WJPDFBoxProvider.createFlattenedPDF(from: newPDFDocument, at: url)
    }
    
    static func createFlattenedPDF(from pdfDocument: PDFDocument, at url: URL) -> Bool  {

        // 为新PDF文件创建临时存储路径
        let newPDFURL = url
        
        // 准备PDF图形上下文
        UIGraphicsBeginPDFContextToFile(newPDFURL.path, CGRect.zero, nil)
        
        guard let context = UIGraphicsGetCurrentContext() else {
            UIGraphicsEndPDFContext()
            return false
        }
        
        // 逐页处理
        for pageIndex in 0..<pdfDocument.pageCount {
            guard let page = pdfDocument.page(at: pageIndex) else { continue }
            
            let pageBounds = page.bounds(for: .mediaBox)
            UIGraphicsBeginPDFPageWithInfo(pageBounds, nil)
            // 将PDF页面绘制到上下文中（这会包含已渲染的注解）
            context.saveGState()
            context.translateBy(x: 0, y: pageBounds.size.height)
            context.scaleBy(x: 1.0, y: -1.0)
            page.draw(with: .mediaBox, to: context)
            context.restoreGState()
        }
        
        // 完成并保存PDF
        UIGraphicsEndPDFContext()
        return true
    }
}

